package customgeneric;

import java.util.ArrayList;
import java.util.List;

/**
 * @author DCSGO
 * @version 1.0
 * 泛型的继承和通配符
 */
public class GenericExtends {
    //1.泛型不具备继承性
    //2.<?> 支持任意泛型类型(类型参数)
    //3.<? extends A> 支持A类以及A类的子类 规定了泛型的上限
    //4.<? super A> 支持A类以及A类的父类 不限于直接父类 规定了泛型的下限
    public static void main(String[] args) {
        //List<Object> list = new ArrayList<String>();//编译错误 泛型不具备继承性
        GenericAll(new ArrayList<Object>());
        GenericAll(new ArrayList<Integer>());
        GenericAll(new ArrayList<String>());
        GenericAll(new ArrayList<A>());
        GenericAll(new ArrayList<B>());
        GenericAll(new ArrayList<C>());

        //GenericExtendsA(new ArrayList<Object>());//编译错误 Object 不是A类以及A类的子类
        //GenericExtendsA(new ArrayList<Integer>());//编译错误 Integer 不是A类以及A类的子类
        //GenericExtendsA(new ArrayList<String>());//编译错误 String 不是A类以及A类的子类
        GenericExtendsA(new ArrayList<A>());
        GenericExtendsA(new ArrayList<B>());
        GenericExtendsA(new ArrayList<C>());

        GenericSuperA(new ArrayList<Object>());
        //GenericSuperA(new ArrayList<Integer>());//编译错误 Integer 不是A类以及A类的父类
        //GenericSuperA(new ArrayList<String>());//编译错误 String 不是A类以及A类的父类
        GenericSuperA(new ArrayList<A>());
        //GenericSuperA(new ArrayList<B>());//编译错误 B 不是A类以及A类的父类
        //GenericSuperA(new ArrayList<C>());//编译错误 C 不是A类以及A类的父类

    }

    public static void GenericAll(List<?> list) {
        System.out.println(list);
    }

    public static void GenericExtendsA(List<? extends A> list) {
        System.out.println(list);
    }

    public static void GenericSuperA(List<? super A> list) {
        System.out.println(list);
    }
}

class A {
}

class B extends A {
}

class C extends B {
    List<?> list = new ArrayList<>();
}
//在Java中 通配符(wildcard)是一种泛型机制 用于表示未知类型
//通配符的使用场景如下:

//1.泛型方法的参数类型限定: 当你定义一个泛型方法 但不确定具体的类型参数时
//  可以使用通配符作为参数类型的限定
//  例如: public void printList(List<?> list)
//  这样可以接受任意类型的List作为参数

//2.泛型类型的上界限定: 使用通配符可以对泛型类型进行上界限定 表示只能接受某个范围内的类型参数
// 例如: public void processData(List<? extends Number> data)
// 表示只能接受 Number 及其子类类型的 List 作为参数

//3.泛型类型的下界限定: 使用通配符也可以对泛型类型进行下界限定 表示只能接受某个范围内的类型参数及其父类型
// 例如: public void addData(List<? super Integer> data)
// 表示只能接受Integer及其父类类型的List作为参数

//4.通配符的限制: 通配符不能用于定义泛型类型的变量或返回值类型
// 例如: List<?> list = new ArrayList<?>(); 是不合法的

//通配符的使用场景取决于具体的需求 通过使用通配符 可以增加代码的灵活性和可重用性 使得代码更具通用性
